package com.gxar.quick.ar.server.base.facade;

import com.gxar.common.exception.APIRuntimeException;
import com.gxar.common.utils.JacksonUtils;
import com.gxar.common.utils.StringSpliceUtils;
import com.gxar.common.utils.StringUtils;
import com.gxar.quick.ar.server.base.common.enums.SketchfabCategoryEnum;
import com.gxar.quick.ar.server.base.common.properties.TranslateProperties;
import com.gxar.quick.ar.server.base.model.material.info.CategoryInfo;
import com.gxar.quick.ar.server.base.model.material.info.DownloadModelInfo;
import com.gxar.quick.ar.server.base.model.material.vo.request.QuerySketchfabModelsRequest;
import com.gxar.quick.ar.server.base.model.material.vo.response.AuthSketchfabResponse;
import com.gxar.quick.ar.server.base.model.material.vo.response.DownloadSketchfabModelResponse;
import com.gxar.quick.ar.server.base.model.material.vo.response.QuerySketchfabCategoryResponse;
import com.gxar.quick.ar.server.base.model.material.vo.response.QuerySketchfabModelsResponse;
import com.gxar.quick.ar.server.base.sdk.BaiduTranslateSDK;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.List;

/**
 * @author nice
 * @version 1.0
 * @created 2023/11/13.
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ExternalMaterialFacade {

    private final TranslateProperties translateProperties;

    private final BaiduTranslateSDK translateSdk;

    public QuerySketchfabModelsResponse querySketchfabModels(QuerySketchfabModelsRequest param) {
        Integer pageNow = param.getPageNow();
        Integer pageSize = param.getPageSize();
        pageNow = pageNow == null ? 1 : pageNow;
        pageSize = pageSize == null ? 10 : pageSize;
        //licence 限制by 参考LicenseEnum
        String url = "https://api.sketchfab.com/v3/search?{}&type=models&q={}&downloadable=true&staffpicked=true&date=&categories={}&license=by&sort_by=-likeCount";
        String cursor = "count=" + pageSize + "&cursor=" + (pageNow - 1) * pageSize;
        url = StringSpliceUtils.splice(url, cursor, StringUtils.isBlank(param.getQuery()) ? Strings.EMPTY: translate(param.getQuery()),
                StringUtils.isBlank(param.getCategorySlug()) ? Strings.EMPTY : param.getCategorySlug());
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();
        try (Response response = client.newCall(request).execute()) {
            QuerySketchfabModelsResponse result = JacksonUtils.parseObject(response.body().string(),
                    QuerySketchfabModelsResponse.class);
            return result;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public AuthSketchfabResponse generateToken(String userName, String password) {
        String clientId = "baGwU8qPfdMgUigvz89gFu3wKouxnxYNIy0B5LQJ";
        String clientSecret = "qvRmI867tdmWukyuI8IgxcvrEXo8njokfnIh1EyGVJUHQFPeDKWg1FRS35daixC5fOdDJpT9fJkXYs2oKwPgNlH3tKSciNsRbiz1GfxCPQUcCVqlmpcYOBfA2yK0sVNh";
        String encode = clientId + ":" + clientSecret;
        String credentials = new String(Base64.getEncoder().encode(encode.getBytes()));
        String url = "https://sketchfab.com/oauth2/token/";
        RequestBody formBody = new FormBody.Builder().add("grant_type", "password").add("username", userName)
                .add("password", password).build();
        Request request = new Request.Builder().url(url).header("Authorization", "Basic " + credentials).post(formBody)
                .build();
        OkHttpClient client = new OkHttpClient();
        try {
            Response response = client.newCall(request).execute();
            return JacksonUtils.parseObject(response.body().string(), AuthSketchfabResponse.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public DownloadSketchfabModelResponse downloadSketchfabModels(String uid, String token) {
        String url = "https://api.sketchfab.com/v3/models/{}/download";
        url = StringSpliceUtils.splice(url, uid);
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(url).header("Authorization", "Bearer " + token).build();
        try (Response response = client.newCall(request).execute()) {
            return JacksonUtils.parseObject(response.body().string(), DownloadSketchfabModelResponse.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public QuerySketchfabCategoryResponse querySketchfabCategory() {
        String url = "https://api.sketchfab.com/v3/categories";
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();
        try (Response response = client.newCall(request).execute()) {
            QuerySketchfabCategoryResponse result = JacksonUtils.parseObject(response.body().string(),
                    QuerySketchfabCategoryResponse.class);
            List<CategoryInfo> results = result.getResults();
            for (CategoryInfo categoryInfo : results) {
                categoryInfo.setChineseName(SketchfabCategoryEnum.getCodeMap().get(categoryInfo.getSlug()));
            }
            return result;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public String downloadSketchfabModelsV2(String uid, String token) {
        DownloadSketchfabModelResponse downloadResponse = downloadSketchfabModels(uid, token);
        DownloadModelInfo glb = downloadResponse.getGlb();
        String url = glb.getUrl();
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();
        try (Response response = client.newCall(request).execute()) {
            ResponseBody responseBody = response.body();
            // 检查响应体是否为空
            if (responseBody != null) {
                // 获取输入流
                InputStream inputStream = responseBody.byteStream();
                // 替换为实际的文件路径
                File outputFile = new File(uid + ".glb");
                // 使用 FileOutputStream 将输入流写入文件
                try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                }
                // 关闭输入流和响应体
                inputStream.close();
                responseBody.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return url;
    }

    /**
     * 翻译
     *
     * @param query 翻译的文本
     * @return 结果
     */
    private String translate(String query) {
        Boolean enable = translateProperties.getEnable();
        if (!enable) {
            return query;
        }
        try {
            return translateSdk.autoTranslateEn(query);
        } catch (APIRuntimeException e) {
            log.info("翻译异常：{}", e.getMessage(), e);
            return query;
        }
    }

}
